<?php

namespace Common\Model;

/**
 * 微信企业付款(https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_1)
 * 发现金红包（https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_1）
 * @author i
 *
 */
class WeixinPayModel
{

    private $URL = "";

    private $hongbao_url = "";

    private $mch_id = "";

    private $wxappid = "";

    private $nick_name = "";

    private $send_name = '';

    private $apikey = "";

    private $cert_path = "";

    private $cert_key_path = "";

    public function __construct($appid)
    {
        $this->URL = C("QIYE_PAY_URL") ? C("QIYE_PAY_URL") : "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
        $this->hongbao_url = C('HONGBAO_PAY_URL') ? C('HONGBAO_PAY_URL') : "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";
        $this->mch_id = C("MCH_ID");
        $this->wxappid = $appid ? $appid : C("AppID");
        $this->nick_name = C('NICK_NAME') ? C('NICK_NAME') : '';
        $this->send_name = C('APP_NAME') ? C('APP_NAME') : '';
        $this->apikey = C("API_KEY");
        $this->cert_path = APP_ROOT . C("CERT_PATH");
        $this->cert_key_path = APP_ROOT . C("CERT_KEY_PATH");
    }

    /**
     * 企业付款
     * 
     * @param unknown $openid            
     * @param unknown $amount            
     * @param string $check_name            
     * @param unknown $re_user_name            
     * @return array
     */
    public function send($openid, $amount, $check_name = 'NO_CHECK', $re_user_name)
    {
        $param = array();
        $nonce_str = md5(time() . rand(10000, 99999));
        $time_tmp = time();
        $time_tmp = substr($time_tmp, 3);
        $random = rand(1000, 9999);
        $random = "{$random}";
        
        $id_apply = new \Common\Model\IdApplyModel();
        $code3 = $id_apply->apply('hongbao');
        
        $mch_billno = date("YmdHis") . $random . $openid . "-" . $code3;
        $mch_id = $this->mch_id;
        $wxappid = $this->wxappid;
        $total_amount = $amount;
        $min_value = $amount;
        $max_value = $amount;
        $total_num = 1;
        $client_ip = "127.0.0.1";
        
        $param['mch_appid'] = $wxappid;
        $param['mchid'] = $mch_id;
        $param['nonce_str'] = $nonce_str;
        $param['partner_trade_no'] = $mch_billno;
        $param['openid'] = $openid;
        $param['check_name'] = $check_name; // 'FORCE_CHECK';//'OPTION_CHECK';//'NO_CHECK';
        
        if ($re_user_name != 'NO_CHECK')
        {
            $param['re_user_name'] = $re_user_name;
        }
        
        $param['amount'] = $amount;
        $param['desc'] = $this->send_name;
        $param['spbill_create_ip'] = $client_ip;
        
        ksort($param);
        $singvalue = $this->getmd5sec($param);
        $xml = "<xml>
				<sign>{$singvalue}</sign>
				<mch_appid>{$param['mch_appid']}</mch_appid>
				<mchid>{$param['mchid']}</mchid>
				<nonce_str>{$param['nonce_str']}</nonce_str>
				<partner_trade_no>{$param['partner_trade_no']}</partner_trade_no>
				<openid>{$param['openid']}</openid>
				<check_name>{$param['check_name']}</check_name>
				<amount>{$param['amount']}</amount>
				<desc>{$param['desc']}</desc>
				<spbill_create_ip>{$param['spbill_create_ip']}</spbill_create_ip>";
        
        if ($re_user_name != 'NO_CHECK')
        {
            $xml .= "<re_user_name>{$param['re_user_name']}</re_user_name>";
        }
        
        $xml .= "</xml>";
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->URL);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        
        curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
        curl_setopt($ch, CURLOPT_SSLCERT, $this->cert_path);
        curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $this->mch_id);
        curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
        curl_setopt($ch, CURLOPT_SSLKEY, $this->cert_key_path);
        
        $result = curl_exec($ch);
        curl_close($ch);
        
        if (curl_errno($ch) > 0)
        {
            my_log("pay qiye curl error:" . $this->URL);
            return false;
        }
        
        $result = str_replace("<![CDATA[", "", $result);
        $result = str_replace("]]>", "", $result);
        
        $rs = simplexml_load_string($result);
        $rs = (array) $rs;
        
        // 记录日志
        $msend = D("sendlog");
        $data['openid'] = $openid;
        $data['appid'] = $wxappid;
        $data['total_amount'] = $amount;
        $data['return_code'] = $mch_billno;
        $data['result_code'] = $rs['result_code'];
        $data['return_msg'] = $rs['return_msg'];
        $data['err_code'] = $rs['err_code'];
        $data['err_code_msg'] = $rs['err_code_msg'];
        $data['mch_billno'] = $rs['mch_billno'];
        $msend->data($data)->add();
        
        return $rs;
    }

    private function getmd5sec($param)
    {
        ksort($param);
        $tmp = "";
        foreach ($param as $k => $v)
        {
            if ($v)
            {
                $tmp .= "{$k}={$v}&";
            }
        }
        $tmp .= "key={$this->apikey}";
        return strtoupper(md5($tmp));
    }

    /**
     * 现金红包
     * 
     * @param unknown $openid            
     * @param unknown $amount            
     * @param unknown $wishing            
     * @param unknown $act_name            
     * @param unknown $remark            
     * @return array
     */
    public function sendRedPacket($openid, $amount, $wishing, $act_name, $remark)
    {
        $param = array();
        $nonce_str = md5(time() . rand(10000, 99999));
        $time_tmp = time();
        $time_tmp = substr($time_tmp, 3);
        $random = rand(1000, 9999);
        $random = "{$time_tmp}{$random}";
        
        $id_apply = new \Common\Model\IdApplyModel();
        $code3 = $id_apply->apply('hongbao');
        
        $mch_billno = $this->mch_id . "" . date("Ymd") . $random . "~" . $code3;
        $mch_id = $this->mch_id;
        $wxappid = $this->wxappid;
        $total_amount = $amount;
        $min_value = $amount;
        $max_value = $amount;
        $total_num = 1;
        $client_ip = "127.0.0.1";
        
        $param['nonce_str'] = $nonce_str;
        $param['mch_billno'] = $mch_billno;
        $param['mch_id'] = $mch_id;
        $param['wxappid'] = $wxappid;
        $param['total_amount'] = $total_amount;
        $param['min_value'] = $min_value;
        $param['max_value'] = $max_value;
        $param['total_num'] = $total_num;
        $param['wishing'] = $wishing;
        $param['client_ip'] = $client_ip;
        $param['act_name'] = $act_name;
        $param['remark'] = $remark;
        $param['nick_name'] = $this->nick_name;
        $param['send_name'] = $this->send_name;
        $param['re_openid'] = $openid;
        ksort($param);
        $singvalue = $this->getmd5sec($param);
        $xml = "<xml>
		<sign>{$singvalue}</sign>
		<mch_billno>{$param['mch_billno']}</mch_billno>
		<mch_id>{$param['mch_id']}</mch_id>
		<wxappid>{$param['wxappid']}</wxappid>
		<nick_name>{$param['nick_name']}</nick_name>
		<send_name>{$param['send_name']}</send_name>
		<re_openid>{$param['re_openid']}</re_openid>
		<total_amount>{$param['total_amount']}</total_amount>
		<min_value>{$param['min_value']}</min_value>
		<max_value>{$param['max_value']}</max_value>
		<total_num>{$param['total_num']}</total_num>
		<wishing>{$param['wishing']}</wishing>
		<client_ip>{$param['client_ip']}</client_ip>
		<act_name>{$param['act_name']}</act_name>
		<remark>{$param['remark']}</remark>
		<nonce_str>{$param['nonce_str']}</nonce_str>
		</xml>";
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->hongbao_url);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        
        curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
        curl_setopt($ch, CURLOPT_SSLCERT, $this->cert_path);
        curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $this->mch_id);
        curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
        curl_setopt($ch, CURLOPT_SSLKEY, $this->cert_key_path);
        
        $result = curl_exec($ch);
        curl_close($ch);
        
        if (curl_errno($ch) > 0)
        {
            my_log('pay redpacket curl error' . $this->hongbao_url);
            return false;
        }
        
        $result = str_replace("<![CDATA[", "", $result);
        $result = str_replace("]]>", "", $result);
        
        $rs = simplexml_load_string($result);
        $rs = (array) $rs;
        
        // 记录日志
        $msend = D("sendlog");
        $data['openid'] = $rs['re_openid'];
        $data['appid'] = $rs['wxappid'];
        $data['total_amount'] = $rs['total_amount'] / 100;
        $data['return_code'] = $rs['return_code'];
        $data['result_code'] = $rs['result_code'];
        $data['return_msg'] = $rs['return_msg'];
        $data['err_code'] = $rs['err_code'];
        $data['err_code_msg'] = $rs['err_code_msg'];
        $data['mch_billno'] = $rs['mch_billno'];
        $msend->data($data)->add();
        return $rs;
    }
}
